<?php
/**
 * Created by PhpStorm.
 * User: My
 * Date: 2020/2/3
 * Time: 19:09
 */

namespace App\Http\Api\V1\Blls;

use App\Exceptions\UserException;
use App\Http\Common\Facade\QuestionFacade;
use App\Http\Common\Facade\RecognitionFacade;
use GuzzleHttp\Client;
use Illuminate\Http\UploadedFile;

class RecognitionBll
{
    protected static function processImage($imagePath)
    {
        $imagick = new \Imagick($imagePath);
        $imagick->scaleImage(28, 28);


        $pixels = [];
        $pixelsIterator = $imagick->getPixelIterator();
        foreach ($pixelsIterator as $row => $pixelList) {
            foreach ($pixelList as $col => $pixel) {
                $blueValue = $pixel->getColorValue(\Imagick::COLOR_BLUE);
                $greenValue = $pixel->getColorValue(\Imagick::COLOR_GREEN);
                $redValue = $pixel->getColorValue(\Imagick::COLOR_RED);
                $pixelVal = $blueValue + $greenValue + $redValue;
                if ($pixelVal < 3) {
                    $pixels[] = $blueValue + $greenValue + $redValue;
                }
            }
        }

        $avgPixel = array_sum($pixels) / count($pixels);
        $filteredPixels = [];

        $pixelsIterator = $imagick->getPixelIterator();
        foreach ($pixelsIterator as $row => $pixelList) {
            foreach ($pixelList as $col => $pixel) {
                $blueValue = $pixel->getColorValue(\Imagick::COLOR_BLUE);
                $greenValue = $pixel->getColorValue(\Imagick::COLOR_GREEN);
                $redValue = $pixel->getColorValue(\Imagick::COLOR_RED);
                $pixelVal = $blueValue + $greenValue + $redValue;
                if ($pixelVal < 3) {
                    if ($pixelVal >= $avgPixel) {
                        $pixel->setColorValue(\Imagick::COLOR_BLUE, 1);
                        $pixel->setColorValue(\Imagick::COLOR_GREEN, 1);
                        $pixel->setColorValue(\Imagick::COLOR_RED, 1);
                        $pixelVal = 3;
                    }
                }
                $filteredPixels[] = $pixelVal;
            }
            $pixelsIterator->syncIterator();
        }

        return $filteredPixels;
    }

    protected static function recognizeImage($imagePath, $type)
    {
        $model = (new \Phpml\ModelManager())->restoreFromFile(
            storage_path($type . '.model')
        );
        return $model->predict(self::processImage($imagePath));
    }

    /**
     * 图片识别口罩
     * @param UploadedFile $sourceImage
     * @param $param
     * @return array
     * @throws UserException
     */
    public static function recognitionImg($sourceImage, $param)
    {
        list($relativeFile, $fileUrl, $attachmentId) = AttachmentBll::uploadImg($sourceImage);
        $imageType = $param['image_type'];
        $recoResult = self::recognizeImage($relativeFile, $imageType);

        //得出结论
        if ($fileUrl) {
            unlink($relativeFile);
        }
        //数据入库
        $recognitionData = [
            'attachment_id' => $attachmentId,
            'answers' => formatArrValue($param, 'answer', ''),
            'reco_result' => $recoResult,
            'final_result' => json_encode($recoResult, JSON_UNESCAPED_UNICODE),
        ];
        RecognitionFacade::save($recognitionData);
        return $recoResult;
    }

    /**
     * 问卷识别口罩
     * @param $param
     * @return array
     */
    public static function recognitionQuestion($param)
    {
        $answer = $param['answer'];
        $cnt = count($answer);
        $realRate = 0;
        foreach ($answer as $key => $value) {
            $question = QuestionFacade::getOneById($key);
            $ansConfig = json_decode($question->ans_config, true);
            $realRate += ($ansConfig[$value] / $cnt);
        }
        $realRate = intval($realRate);
        if ($realRate > 80) {
            $useRemark = '请放心使用';
        } elseif ($realRate > 60) {
            $useRemark = '请谨慎使用';
        } else {
            $useRemark = '建议不要使用';
        }
        $finalResult = [
            'real_rate' => $realRate,
            'remark' => [
                "根据您的观察，口罩{$realRate}%为真，{$useRemark}",
            ]

        ];
        $recognitionData = [
            'attachment_id' => 0,
            'answers' => json_encode($param['answer'], JSON_UNESCAPED_UNICODE),
            'reco_result' => 0,
            'final_result' => json_encode($finalResult, JSON_UNESCAPED_UNICODE),
        ];
        RecognitionFacade::save($recognitionData);
        return $finalResult;
    }

    /**
     * 识别图片中未戴口罩的人
     * @param $imagePath
     * @param $imageExt
     * @return array|mixed
     */
    public static function maskDetect($imagePath, $imageExt)
    {
        //Call paddle mask detection api
        $httpClient = new Client();
        $response = $httpClient->post('http://127.0.0.1:8866/predict/image/pyramidbox_lite_server_mask', [
            'multipart' => [
                [
                    'name'     => 'image',
                    'contents' => fopen($imagePath, 'r'),
                    'filename' => uniqid() . '.' . $imageExt,
                ],
            ],
        ]);
        if ($response->getStatusCode() === 200) {
            $detectResult = json_decode($response->getBody()->getContents(), true);
            if (is_array($detectResult)) {
                if (isset($detectResult['results'])) {
                    if (is_array($detectResult['results'])) {
                        return $detectResult['results'];
                    }
                    if (is_string($detectResult['results'])) {
                        $results = json_decode(str_replace('\'', '"', $detectResult['results']), true);
                        if (is_array($results)) {
                            return $results;
                        }
                    }
                }
            }
        }

        return [];
    }
}
